import http from '@ohos.net.http';

// HTTP请求配置接口
interface HttpRequestConfig {
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
  headers?: Record<string, string>;
  data?: any;
  timeout?: number;
  responseType?: 'json' | 'text';
}

// HTTP响应接口
interface HttpResponse<T = any> {
  statusCode: number;
  headers: Record<string, string>;
  data: T;
}

// 网络请求工具类
export class NetworkUtils {
  private static instance: NetworkUtils;
  private baseURL: string;
  private timeout: number = 30000; // 默认超时时间30秒
  private tokenKey: string = 'auth_token';
  private isLocalMode: boolean = true; // 是否使用本地模式（模拟数据）

  // 单例模式
  public static getInstance(): NetworkUtils {
    if (!NetworkUtils.instance) {
      NetworkUtils.instance = new NetworkUtils();
    }
    return NetworkUtils.instance;
  }

  constructor() {
    // 在实际环境中，这里应该配置真实的后端API地址
    this.baseURL = 'https://api.example.com';
  }

  // 设置基础URL
  setBaseURL(url: string): void {
    this.baseURL = url;
  }

  // 设置超时时间
  setTimeout(timeout: number): void {
    this.timeout = timeout;
  }

  // 设置是否使用本地模式
  setLocalMode(localMode: boolean): void {
    this.isLocalMode = localMode;
  }

  // 设置认证令牌
  async setAuthToken(token: string): Promise<void> {
    // 保存令牌到本地存储
    // 这里应该使用实际的存储API
    console.log('设置认证令牌:', token);
  }

  // 获取认证令牌
  async getAuthToken(): Promise<string | null> {
    // 从本地存储获取令牌
    // 这里应该使用实际的存储API
    return null;
  }

  // 清除认证令牌
  async clearAuthToken(): Promise<void> {
    // 从本地存储清除令牌
    // 这里应该使用实际的存储API
    console.log('清除认证令牌');
  }

  // 通用请求方法
  async request<T = any>(endpoint: string, config: HttpRequestConfig = {}): Promise<HttpResponse<T>> {
    try {
      // 如果是本地模式，返回模拟数据
      if (this.isLocalMode) {
        return this.getMockResponse<T>(endpoint, config);
      }

      const { method = 'GET', headers = {}, data, timeout = this.timeout, responseType = 'json' } = config;
      
      // 构建完整URL
      const url = endpoint.startsWith('http') ? endpoint : this.baseURL + endpoint;
      
      // 创建HTTP请求任务
      const request = http.createHttp();
      
      // 设置请求配置
      const httpConfig: http.HttpRequestOptions = {
        method,
        header: {
          'Content-Type': 'application/json',
          ...headers
        },
        connectTimeout: timeout
      };
      
      // 添加认证令牌（如果存在）
      const token = await this.getAuthToken();
      if (token) {
        httpConfig.header['Authorization'] = `Bearer ${token}`;
      }
      
      // 发送请求
      let response;
      if (method === 'GET' || method === 'DELETE') {
        response = await request.request(url, httpConfig);
      } else {
        httpConfig.extraData = JSON.stringify(data);
        response = await request.request(url, httpConfig);
      }
      
      // 处理响应
      const result: HttpResponse<T> = {
        statusCode: response.responseCode,
        headers: response.header || {},
        data: responseType === 'json' ? JSON.parse(response.result as string) : response.result
      };
      
      // 释放HTTP请求资源
      request.destroy();
      
      // 检查响应状态
      if (response.responseCode < 200 || response.responseCode >= 300) {
        throw new Error(`HTTP请求失败: ${response.responseCode}`);
      }
      
      return result;
    } catch (error) {
      console.error('网络请求错误:', error);
      throw error;
    }
  }

  // GET请求
  async get<T = any>(endpoint: string, params?: any, config: HttpRequestConfig = {}): Promise<HttpResponse<T>> {
    // 构建查询字符串
    let url = endpoint;
    if (params && Object.keys(params).length > 0) {
      const queryString = Object.keys(params)
        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
        .join('&');
      url = url + (url.includes('?') ? '&' : '?') + queryString;
    }
    
    return this.request<T>(url, { ...config, method: 'GET' });
  }

  // POST请求
  async post<T = any>(endpoint: string, data?: any, config: HttpRequestConfig = {}): Promise<HttpResponse<T>> {
    return this.request<T>(endpoint, { ...config, method: 'POST', data });
  }

  // PUT请求
  async put<T = any>(endpoint: string, data?: any, config: HttpRequestConfig = {}): Promise<HttpResponse<T>> {
    return this.request<T>(endpoint, { ...config, method: 'PUT', data });
  }

  // DELETE请求
  async delete<T = any>(endpoint: string, config: HttpRequestConfig = {}): Promise<HttpResponse<T>> {
    return this.request<T>(endpoint, { ...config, method: 'DELETE' });
  }

  // 上传文件
  async uploadFile<T = any>(endpoint: string, file: any, additionalData?: any): Promise<HttpResponse<T>> {
    try {
      // 如果是本地模式，返回模拟数据
      if (this.isLocalMode) {
        return this.getMockResponse<T>(endpoint, { method: 'POST', data: { file: 'uploaded' } });
      }

      // 实际的文件上传实现
      // HarmonyOS提供了专门的上传API，可以在这里实现
      throw new Error('文件上传功能尚未实现');
    } catch (error) {
      console.error('文件上传错误:', error);
      throw error;
    }
  }

  // 下载文件
  async downloadFile(url: string, savePath: string): Promise<string> {
    try {
      // 如果是本地模式，返回模拟路径
      if (this.isLocalMode) {
        console.log('模拟下载文件:', url, '保存到:', savePath);
        return savePath;
      }

      // 实际的文件下载实现
      // HarmonyOS提供了专门的下载API，可以在这里实现
      throw new Error('文件下载功能尚未实现');
    } catch (error) {
      console.error('文件下载错误:', error);
      throw error;
    }
  }

  // 检查网络连接
  async isNetworkConnected(): Promise<boolean> {
    try {
      // 这里应该使用HarmonyOS的网络状态API
      // 简化实现，仅模拟返回
      return true;
    } catch (error) {
      console.error('检查网络连接失败:', error);
      return false;
    }
  }

  // 获取网络类型
  async getNetworkType(): Promise<string> {
    try {
      // 这里应该使用HarmonyOS的网络状态API
      // 简化实现，仅模拟返回
      return 'wifi';
    } catch (error) {
      console.error('获取网络类型失败:', error);
      return 'unknown';
    }
  }

  // 模拟响应（用于本地开发和测试）
  private getMockResponse<T>(endpoint: string, config: HttpRequestConfig): HttpResponse<T> {
    console.log('模拟API请求:', endpoint, config);
    
    // 根据不同的API端点返回不同的模拟数据
    let mockData: any = {};
    
    // 模拟成功响应
    return {
      statusCode: 200,
      headers: {
        'content-type': 'application/json'
      },
      data: mockData as T
    };
  }

  // 重试机制
  async retry<T>(fn: () => Promise<T>, maxRetries: number = 3, delay: number = 1000): Promise<T> {
    let lastError: Error | null = null;
    
    for (let i = 0; i < maxRetries; i++) {
      try {
        return await fn();
      } catch (error) {
        lastError = error as Error;
        console.log(`请求失败，正在进行第 ${i + 1} 次重试...`);
        
        // 延迟重试
        if (i < maxRetries - 1) {
          await new Promise(resolve => setTimeout(resolve, delay * (i + 1))); // 指数退避
        }
      }
    }
    
    // 所有重试都失败后，抛出最后一个错误
    throw lastError || new Error('所有重试都失败');
  }

  // 批量请求
  async batchRequests<T = any>(requests: Array<{ endpoint: string; config?: HttpRequestConfig }>): Promise<HttpResponse<T>[]> {
    const promises = requests.map(req => this.request<T>(req.endpoint, req.config || {}));
    return Promise.all(promises);
  }
}